package net.interneteidee.dao;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import net.interneteidee.entity.Categoria;
import net.interneteidee.entity.Cliente;
import net.interneteidee.entity.Cliente_;
import net.interneteidee.entity.Fattura;
import net.interneteidee.entity.Fattura_;
import net.interneteidee.entity.Ordine;
import net.interneteidee.entity.Ordine_;

@Stateless
public class FatturaDao extends GenericDao<Fattura> {

	
	public FatturaDao() {
		// TODO Auto-generated constructor stub
		super(Fattura.class);

	}
	
	/**
	 * Restituisce le Fatture la cui dataEmissione rientra nel range dataDa dataA
	 * e hanno uno stato corretto 
	 * @param dataDa
	 * @param dataA
	 * @param stato può essere evasi , da evadere e da fatturare
	 * @return
	 */
	public List<Fattura> findFatturaByStato(Date dataDa,Date dataA,String stato){
		
		List<Fattura> fatture = new LinkedList<Fattura>();
		
		criteriaQuery = criteriaBuilder.createQuery(Fattura.class);
		Root<Fattura> rootFattura = criteriaQuery.from(Fattura.class);
		
		Predicate predicatoDataRange = criteriaBuilder.between(rootFattura.get(Fattura_.dataEmissione),dataDa,dataA);
		Predicate predicatoStato =   criteriaBuilder.equal(rootFattura.get(Fattura_.stato), stato);
		
		//Seleziono tutti gli ordini di un dato cliente senza tener conto dello stato
		if(stato.equals("Tutte")) 
			criteriaQuery.select(rootFattura).distinct(true).where(criteriaBuilder.and(predicatoDataRange));
				
		//Seleziono tutti gli ordini di un dato cliente tenendo conto di un cliente
		else 
			criteriaQuery.select(rootFattura).distinct(true).where(criteriaBuilder.and(predicatoDataRange,predicatoStato));
														

		fatture = entityManager.createQuery(criteriaQuery).getResultList();
		
		return fatture;
	
	}
	
	
	
	/**
	 * Restituisce gli ordini di un dato Cliente la cui dataAccettazione rientra nel range dataDa dataA
	 * e hanno uno stato corretto 
	 * @param dataDa
	 * @param dataA
	 * @param stato può essere evasi , da evadere e da fatturare
	 * @return
	 */
	public List<Fattura> findFatturaDiUnDatoClienteByStato(Date dataDa,Date dataA,String stato, String principalCliente){
		
		
		criteriaQuery = criteriaBuilder.createQuery(Fattura.class);
		Root<Fattura> rootFattura = criteriaQuery.from(Fattura.class);

		Join<Fattura,Cliente> joinConCliente = rootFattura.join(Fattura_.cliente);

		
		Predicate predicatoDataRange = criteriaBuilder.between(rootFattura.get(Fattura_.dataEmissione),dataDa,dataA);
		Predicate predicatoPrincipal =   criteriaBuilder.equal(joinConCliente.get(Cliente_.principal), principalCliente);
		Predicate predicatoStato =   criteriaBuilder.equal(rootFattura.get(Fattura_.stato), stato);


		List<Fattura> fatture = new LinkedList<Fattura>();

	
		//Seleziono tutti gli ordini di un dato cliente senza tener conto dello stato
		if(stato.equals("Tutte")) 
			criteriaQuery.select(rootFattura).distinct(true).where(criteriaBuilder.and(predicatoDataRange,predicatoPrincipal));
		
		
		//Seleziono tutti gli ordini di un dato cliente tenendo conto di un cliente
		else 
			criteriaQuery.select(rootFattura).distinct(true).where(criteriaBuilder.and(predicatoDataRange,predicatoStato,predicatoPrincipal));
		
		
		fatture = entityManager.createQuery(criteriaQuery).getResultList();
		return fatture;
		
		
	}
	
	/**
	 * Seleziona tutte le fatture che hanno una data di scadenza inferiore a quella odierna
	 */
	public List<Fattura> findFattureInScadenza(){
		
		Calendar cal = new GregorianCalendar();
		
		criteriaQuery = criteriaBuilder.createQuery(Fattura.class);
		Root<Fattura> rootFattura = criteriaQuery.from(Fattura.class);
		
		Predicate predicatoData = criteriaBuilder.lessThan(rootFattura.get(Fattura_.dataScadenza),cal.getTime());
		
		criteriaQuery.select(rootFattura).where(predicatoData);

		List<Fattura> fatture = new LinkedList<Fattura>();
		
		fatture = entityManager.createQuery(criteriaQuery).getResultList();
		
		return fatture;

	}
	
}
